import { BuildParams } from "../BuildParams.js";
import { CmdOption } from "../CmdOption.js";
import fs from 'fs-extra';
import path from 'path';
import { ChannelCfg, ChannelCfgDoc, SolutionCfg } from "../typings";
import { findOption } from "../tools/vendor.js";
import _ from "lodash";

export class PlatformCfgParser {
    private cfgs?: ChannelCfg[];
    private cfgMap?: {[gameid: number]: ChannelCfg};

    async getChannelCfg(option: CmdOption, params: BuildParams) {
        if(!this.cfgMap) {
            this.cfgMap = {};
            const cfgpath = path.join(params.workSpacePath, params.platformPath, 'cfg.json');
            console.log(`cfgpath: ${cfgpath}`);
            const cfgDoc = await fs.readJSON(cfgpath) as ChannelCfgDoc;

            let cfgs: ChannelCfg[];
            if ('channels' in cfgDoc) {
                cfgs = cfgDoc.channels;
            } else {
                cfgs = cfgDoc;
            }
            
            if ('global' in cfgDoc) {
                const globalCfg = cfgDoc.global;
                params.projGlobalCfg = globalCfg;
            }
            const solutionMap: { [name: string]: SolutionCfg } = {};
            if ('solutions' in cfgDoc) {
                cfgDoc.solutions?.list?.forEach((v) => solutionMap[v.solutionName] = v);
            }
            for (let i = 0, len = cfgs.length; i < len; i++) {
                let newCfg: Partial<ChannelCfg>;
                if (params.projGlobalCfg != null) {
                    // 先提取global配置
                    newCfg = Object.assign({}, params.projGlobalCfg);
                } else {
                    newCfg = {};
                }
                // 再提取solution配置
                const cfg = cfgs[i];
                if (cfg.solutions != null) {
                    for (const solutionName of cfg.solutions) {
                        const solution = solutionMap[solutionName];
                        if (solution != null) {
                            newCfg = Object.assign(newCfg, solution);
                        } else {
                            console.error('solution not exists:', solutionName);
                            process.exit(1);
                        }
                    }
                }
                newCfg = Object.assign(newCfg, cfgs[i]);
                // 由于目前bundleId都说会配的，而原先安卓包和苹果包还要分别配置apk和ipa，相当愚蠢
                // 直接根据bundleId生成默认的apk和ipa，这样一个gameID可以同时构多个platform
                if (!newCfg.apk) {
                    newCfg.apk = newCfg.bundleId + '.v{version}.apk';
                }
                if (!newCfg.ipa) {
                    newCfg.ipa = newCfg.bundleId;
                }
                cfgs[i] = newCfg as ChannelCfg;
            }
            this.cfgs = cfgs;
        
            const allLangs: string[] = [];
            for(let c of cfgs) {
                this.cfgMap[c.gameid] = c;
                if(undefined == c.plat) {
                    c.plat = 0;
                }
                // 提取所有语言
                if (c['localize-params']) {
                    const localizeParams = c['localize-params'].split(/\s+/);
                    const langs = findOption(localizeParams, '--langs');
                    if (langs) {
                        allLangs.push(...langs.split(','));
                    }
                }
            }
            params.allLangs = _.uniq(allLangs);
        }
    
        const gameid = Number(option.gameIds.split('--')[0]);
        params.channelCfg = this.cfgMap[gameid]!;
        if(!params.channelCfg) {
            console.error(`未找到对应的GameID：${gameid}`);
            process.exit(1);
        }
    }

    getCfgByGameId(gameid: number) {
        return this.cfgMap ? this.cfgMap[gameid] : null;
    }

    getAll() {
        return this.cfgs;
    }
}